package serviceWeb;

import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.restlet.data.CharacterSet;
import org.restlet.data.MediaType;
import org.restlet.data.Status;
import org.restlet.ext.xml.DomRepresentation;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Put;
import org.restlet.resource.ServerResource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

/**
 * Ressource permettant de renvoyer, mettre à jour ou supprimer un enregistrement d'une table
 */
public class RecordResource extends ServerResource {

  EchangeBDXML record;

  String nomBD;
  String nomTable;
  String identifiant;

  /** Representation retournée */
  Representation resultat;
  /** Erreurs possibles */
  List<String> erreurs;

 /** Initialisation de la ressource a partir de la chaine d'url
   */
  protected void init() {

    nomBD = getRequest().getAttributes().get("nomBD").toString();
    nomTable = getRequest().getAttributes().get("nomTable").toString();
    identifiant = getRequest().getAttributes().get("identifiant").toString();
    
    record = new serviceWeb.modelePostgreSQL.EchangeBDXML();
  
  }

  /** Représentation XML (en UTF8) en réponse à une requête GET.
   * <br/>
   * Retour possible : 200, 401 avec idNotInteger, 404, 500 (si
   * problème avec la BD)
   */
  @Get
  public Representation doGet() {
    init();
    if (getStatus() == Status.SUCCESS_OK) {

      assert record != null;
      try
      {
        DomRepresentation dom = new DomRepresentation(MediaType.TEXT_XML);

        record.getRecord(nomBD, nomTable, identifiant);
       
        InputStream binaryStream = record.getXML().getBinaryStream();

        DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = parser.parse(binaryStream);

        FonctionsServerResource.ajouterContraintes(doc, record, nomBD, nomTable);
        
        dom.setDocument(doc);
      
        // Encodage en UTF-8
        dom.setCharacterSet(CharacterSet.UTF_8);
        resultat = dom;
      }
      catch (IOException exc) {
        setStatus(Status.SERVER_ERROR_INTERNAL);
        exc.printStackTrace();
      }
      catch (SQLException exc) {
          setStatus(Status.SERVER_ERROR_INTERNAL);
          //resultat = new StringRepresentation(exc.getMessage());
          resultat = new StringRepresentation(exc.getCause().getMessage());
          exc.printStackTrace();
      }
      catch (ParserConfigurationException exc) {
          setStatus(Status.SERVER_ERROR_INTERNAL);
          resultat = new StringRepresentation(exc.getMessage());
          exc.printStackTrace();
      }
      catch (SAXException exc) {
          setStatus(Status.SERVER_ERROR_INTERNAL);
          resultat = new StringRepresentation(exc.getMessage());
          exc.printStackTrace();
      }
    }
    return resultat;
  }
  

  /** Mise a jour d'un enregistrement.
   */
  @Put
  public Representation doPut(Representation entity) throws SQLException {

      EchangeBDXML modifierRecord = new serviceWeb.modelePostgreSQL.EchangeBDXML();

      init();

      DomRepresentation dom = new DomRepresentation(entity);

      try
      {
          //Récupération de l'XML reçu du client web
          Document doc = dom.getDocument();
          Element table = doc.getDocumentElement();
          Node row = table.getFirstChild();

          Map<String, String> valeurs = new HashMap<String, String>();

          //Pour chaque colonne de l'enregistrement
          for(int i = 0 ; i < row.getChildNodes().getLength() ; i++)
          {
              String nomColonne = row.getChildNodes().item(i).getNodeName();

              Node contenuColonne = row.getChildNodes().item(i).getFirstChild();

              String contenuColonneText = "'";
              if(contenuColonne != null)
                  contenuColonneText += contenuColonne.getTextContent();
              contenuColonneText += "'";

              valeurs.put(nomColonne, contenuColonneText);
          }

          modifierRecord.putRecord(nomBD, nomTable, identifiant, valeurs);
          resultat = entity;
      }
      catch(IOException e)
      {
          setStatus(Status.SERVER_ERROR_INTERNAL);
          resultat = new StringRepresentation(e.getMessage());
          e.printStackTrace();
      }
      catch(SQLException e)
      {
          setStatus(Status.SERVER_ERROR_INTERNAL);
          resultat = new StringRepresentation(e.getMessage());
          e.printStackTrace();
      }

      return resultat;

  }

  /**
   * Suppression d'un enregistrement
   */
  @Delete
  public Representation doDelete() throws SQLException {

      EchangeBDXML deleteRecord = new serviceWeb.modelePostgreSQL.EchangeBDXML();

      init();

      deleteRecord.deleteRecord(nomBD, nomTable, identifiant);

    return resultat;
  }

  /**
   * Renommer un élément
   * N'a pas été utilisé car ne gère pas les attributs
   * @param e : l'élément à renommer
   * @param newName : le nouveau nom
   * @return l'élément renommé
   */
  static Element renameElement(Element e, String newName) {
        Document doc = e.getOwnerDocument();
        Element newElement = doc.createElement(newName);
        while(e.hasChildNodes()) {
            newElement.appendChild(e.getFirstChild());
        }

       /* NamedNodeMap ac = e.getAttributes();
        for(int i = 0 ; i < ac.getLength() ; i++)
            newElement.setAttributeNode((Attr) ac.item(i));*/

        /*XmlAttributeCollection ac = e.Attributes;
        while (ac.Count > 0) {
            newElement.Attributes.Append(ac[0]);*/


        Node parent = e.getParentNode();
        parent.replaceChild(newElement, e);
        return newElement;
    }
  
}
